var refineMaterailId = 49;
function getEquipType(equip){
    var equipType = 'Weapon';

    if( equip.type == 'magic' || equip.type == 'weapon' ) {
        equipType = 'Weapon';
    }else if( equip.type == 'armor' ) {
        equipType = 'Armor';
    }else if( equip.type == 'accessory' ) {
        equipType = 'Accessory';
    }

    return equipType;
}

exports.make = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.eid) || isNaN(req.args.lucky) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }
        
        // 是否百分百打造
        var isForge = req.args.forge ? true : false;

        var eid = +req.args.eid;

        var user = player.user;
        var maxLucky = 3;
        if( user.status.vip ) {
            maxLucky += gConfVip[user.status.vip].LuckyGemAdd;
        }
        var lucky = Math.floor(+req.args.lucky);
        if( lucky < 0 || lucky > maxLucky ){
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var luckyId = +gConfGlobal.LuckyGemId;
        if( lucky > 0 ) {
            if( player.getInventory('material', luckyId) < lucky ) {
                resp.code = 1; resp.desc = 'not enough lucky'; break;
            }
        }
        
        var forgeMaterial = gConfGlobal.ForgeSuccessMaterialId;
        if( isForge ) {
            if( player.getInventory('material', forgeMaterial) < 1 ) {
                resp.code = 1; resp.desc = 'not enough forge100 material'; break;
            } 
        }

        var equip = user.equip[eid];
        if( !equip ) {
            resp.code = 1; resp.desc = 'no equip'; break;
        }

        if( !gConfEquip[equip.level+1] ) {
            resp.code = 1; resp.desc = 'up to max'; break;
        }

        // 判断资源需求
        var materialEnough = true;
        var materialCost = {};
        var equipConf = gConfEquip[equip.level]
        var equipType = getEquipType(equip);
        var materialId = 0;
        var materialNum = 0;
        for( var i=1; i<=2; i++ ) {
            materialId = +equipConf[equipType+'MaterialType'+i]
            materialNum = +equipConf[equipType+'Material'+i];
            if( player.getInventory('material', materialId) < materialNum ) {
                materialEnough = false;
                break;
            }
        }

        if( !materialEnough ) {
            resp.code = 1; resp.desc = 'no enough material'; break;
        }

        for( var i=1; i<=2; i++ ) {
            materialId = +equipConf[equipType+'MaterialType'+i]
            materialNum = -equipConf[equipType+'Material'+i];
            materialCost[materialId] = materialNum;
            player.addInventory('material', materialId, materialNum); 
        }
        
        if( lucky > 0 ) {
            materialCost[luckyId] = -lucky;
            player.addInventory('material', luckyId, -lucky); 
        }

        var equipSuccess = lucky*gConfGlobal.LuckyGemSuccess + equipConf[equipType+'Success'];
        if( isForge ) {
            materialCost[forgeMaterial] = -1;
            player.addInventory('material', forgeMaterial, -1); 
            equipSuccess = 100; 
        } else {
            if( user.status.vip ) {
                equipSuccess += gConfVip[user.status.vip].MakeEquipAdd;
            }

            if( !equip.hasOwnProperty('fail') ) {
                equip.fail = 0;
            }

            equipSuccess += equipConf.EquipAddSuccByFail * equip.fail;  
            
            // 打造100%活动, 或者使用100%成功道具
            var activitySchedule = findActivitySchedule('forge100');
            if( activitySchedule ) {
                equipSuccess = 100; 
            }
        }

        if( common.randRange(1, 100) <= equipSuccess ) {
            equip.level += 1;
            player.markDirty(util.format('equip.%d.level', eid));
            equip.fail = 0; 

            player.doTask('Make'+equipType+'To',equip.level); 
            if( equip.level > 13 ) {
                gMessage.addSystemMessage('equip_make', [user.info.un, gConfEquip[equip.level][equip.type.capWord()+'Name']]);
            }
            
            var newForgeLevelEquip = user.activity.new_forge_level.equip;
            if( equip.level > newForgeLevelEquip[equip.type] ) {
                newForgeLevelEquip[equip.type] = equip.level;
                player.markDirty(util.format('activity.new_forge_level.equip.%s', equip.type));
            }
            
        }else {
            equip.fail += 1;
        }

        player.markDirty(util.format('equip.%d.fail', eid));
        player.roleDirty = true;

        resp.data.level = equip.level;
        resp.data.material = materialCost;

        player.doEventEquipMake(equip);
    }while(false);

    onHandled();
}

exports.strengthen = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.eid) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var eid = +req.args.eid;

        var user = player.user;

        var equip = user.equip[eid];
        if( !equip ) {
            resp.code = 1; resp.desc = 'no equip'; break;
        }
        
        if( equip.strength >= user.status.level ) {
            resp.code = 1; resp.desc = 'reach user level'; break;
        }

        if (!gConfStrengthen[equip.strength + 1]) {
            resp.code = 1; resp.desc = 'reach to max'; break;
        }

        var isTenTimes = (+req.args.ten > 0) ? true : false;
        var expectTimes = 1;
        if( isTenTimes ) {
            var diffLevel = user.status.level - equip.strength;
            expectTimes = ( diffLevel > 10 ) ? 10 : diffLevel;
        }
        
        var equipStrength = equip.strength;
        var goldCostSum = 0;
        var isFullLevel = false;
        for( var i = 0; i < expectTimes; i++ ) {
            if( !gConfStrengthen[equip.strength+1] ) {
                isFullLevel = true; break;
            }    

            var strengthenConf = gConfStrengthen[equipStrength];
            var equipType = getEquipType(equip);
            goldCost = +strengthenConf[equipType+"Cost"]; 
            if( user.status.gold < goldCostSum + goldCost ) {
                break;    
            }    
            
            equipStrength += 1;
            goldCostSum += goldCost;
        }

        if( !goldCostSum ) {
            resp.code = 1; resp.desc = 'not enough gold'; break; 
        }
        
        player.costResource('gold', goldCostSum);

        equip.strength = equipStrength;
        player.markDirty(util.format('equip.%d.strength', eid));
        player.roleDirty = true;

        player.doDailyTask(gConfDailyTask.StrengthenEquip);
        player.doEventEquipStrength(equip);

        resp.data.strength = equipStrength;
        resp.data.gold = -goldCostSum;
        resp.daily_task = gConfDailyTask.StrengthenEquip;

    }while(false);

    onHandled();
}

exports.upgrade_star = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.eid) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var eid = +req.args.eid;

        var user = player.user;
        if( user.status.level < gConfGlobal.EquipStarLevelLimit ) {
            resp.code = 1; resp.desc = 'level not reach'; break;
        }

        var equip = user.equip[eid];
        if( !equip ) {
            resp.code = 1; resp.desc = 'no equip'; break;
        }

        if( !gConfEquipStar[equip.star+1] ) {
            resp.code = 1; resp.desc = 'up to max'; break;
        }

        var equipStarConf = gConfEquipStar[equip.star];
        var materialNum = equipStarConf.Num;
        var materialNeedNum = materialNum;
        var material = {};

        // 优先消耗
        var prioMaterialId = equipStarConf.Material1;
        if( equip.star >= gConfGlobal.EquipStarMaterialLevel && prioMaterialId ) {
            var ownMaterial = player.getInventory('material', prioMaterialId );
            if( ownMaterial > 0 ) {
                var costMaterialNum = materialNeedNum;
                if( ownMaterial < materialNeedNum ) {
                    costMaterialNum = ownMaterial;
                }
                material[prioMaterialId] = -costMaterialNum;
                materialNeedNum -= costMaterialNum;
            }
        }

        var materialId = equipStarConf.Material;
        if( materialNeedNum > 0 ) {
            if( player.getInventory('material', materialId) < materialNeedNum ) {
                resp.code = 1; resp.desc = 'not enough material'; break;
            }
            material[materialId] = -materialNeedNum;
        }

        if( !player.costResource('soul', equipStarConf.Soul) ) {
            resp.code = 1; resp.desc = 'not enough soul'; break;
        }
        
        if( common.randRange(1, 100) <= equipStarConf.Rate ) {
            // 成功
            equip.star += 1;
            if( equip.star > 8 ) {
                gMessage.addSystemMessage('equip_star', [user.info.un, gConfEquip[equip.level][equip.type.capWord()+'Name'], equip.star]);
            }
        }else{
            equip.star = equipStarConf.Demote;
        }

        player.markDirty(util.format('equip.%d.star', eid));
        for( var mid in material ) {
            player.addInventory('material', +mid, material[mid]);
        }

        resp.data.star = equip.star;
        resp.data.soul = -equipStarConf.Soul;
        resp.data.material = material;
        
        player.doEventEquipUpgradeStar(equip);
    }while(false);

    onHandled();
}

// 装备转生升阶
exports.upgrade_refine_level = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.eid) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var eid = +req.args.eid;

        var user = player.user;

        var equip = user.equip[eid];
        if( !equip ) {
            resp.code = 1; resp.desc = 'no equip'; break;
        }
         
        if( gConfEquip[equip.level + 1] ) {
            resp.code = 1; resp.desc = 'not reach level'; break;
        }
        
        var equipRefineLevel = equip.refine_level || 0;
        var equipRefineConf = gConfEquipRefine[equipRefineLevel];
        if( !equipRefineConf ) {
            resp.code = 1; resp.desc = 'to max'; break;
        }

        var materialId = equipRefineConf.Material; 
        var materialCostNum = equipRefineConf.MaterialNum;
        if( player.getInventory('material', materialId) < materialCostNum ) {
            resp.code = 1; resp.desc = 'not enough material'; break;
        }
        
        var equipType = getEquipType(equip);
        var refineAttrs = {};
        var isOpen = false;
        if( !equip.refine || Object.keys(equip.refine).length == 0 ) {
            // 洗练的属性
            var attrs = {
                'attack': 1,
                'defence': 1,
                'mdefence': 1, 
                'health': 1,
                'fortitude': 1,
                'hit': 1,
                'unblock': 1,
                'block' : 1,
                'critdamage': 1,
                'miss': 1,
            };
            
            for( var attr in attrs ) {
                if( !equipRefineConf.hasOwnProperty(util.format('%s%s',equipType, attr.capWord())) ) continue;  
                refineAttrs[attr] = 0;
            }

            isOpen = true;
        }
        
        if( Object.keys(refineAttrs).length == 0 ) {
            refineAttrs = equip.refine;
        }

        var canUpgrade = true;
        for( var attr in refineAttrs ) {
            refineAttrs[attr] = (equip.refine ? (equip.refine[attr] || 0) : 0); 
            if( refineAttrs[attr] < equipRefineConf[equipType + attr.capWord() + 'Limit'] ) {
                canUpgrade = false;
                break; 
            }
        }
        
        if( !canUpgrade ) {
            resp.code = 1; resp.desc = 'refine not reach max'; break;
        }
        
        if( isOpen ) {
            equip.refine_level = 0; 
            equip.refine = refineAttrs;
            player.markDirty(util.format('equip.%d.refine', eid));
        }

        equip.refine_level += 1;
        player.markDirty(util.format('equip.%d.refine_level', eid));

        player.addInventory('material', materialId, -materialCostNum);
        player.roleDirty = true;
        
        gMessage.addSystemMessage('upgrade_refine_level', [user.info.un, gConfEquip[equip.level][equip.type.capWord()+'Name'], equip.refine_level]);

        var retMaterial = {};
        retMaterial[materialId] = -materialCostNum;

        resp.data.material = retMaterial;
    }while(false);

    onHandled();
}

exports.refine = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.eid) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var eid = +req.args.eid;

        var user = player.user;

        var equip = user.equip[eid];
        if( !equip ) {
            resp.code = 1; resp.desc = 'no equip'; break;
        }
        
        if( !equip.refine_level ) {
            resp.code = 1; resp.desc = 'not reach'; break;
        }
        
        var equipRefine = equip.refine;
        var equipRefineLevel = equip.refine_level;
        var equipRefineConf = gConfEquipRefine[equipRefineLevel];
        var equipType = getEquipType(equip);

        var materialId = equipRefineConf.Material; 
        var materialCostNum = equipRefineConf[equipType+'MaterialNum'];
        if( player.getInventory('material', materialId) < materialCostNum ) {
            resp.code = 1; resp.desc = 'not enougth material'; break;
        }
        
        var weights = {};
        var equipRefineLimit = {};
        for( var attr in equipRefine ) {
            equipRefineLimit[attr] = equipRefineConf[util.format('%s%sLimit',equipType, attr.capWord())];
            if( equipRefine[attr] >= equipRefineLimit[attr] ) continue;
            weights[attr] = 1;
        }

        if( Object.keys(weights).length == 0 ) {
            resp.code = 1; resp.desc = 'to level max'; break;
        }

        player.addInventory('material', materialId, -materialCostNum);
        
        var selecetAttr = common.wRand(weights);
        var attrAdd = Math.min(common.randRange(equipRefineConf.RefineMin, equipRefineConf.RefineMax), 
            (equipRefineLimit[selecetAttr] - equipRefine[selecetAttr]));

        equipRefine[selecetAttr] += attrAdd;
        
        player.markDirty(util.format('equip.%d.refine.%s', eid, selecetAttr));
        player.roleDirty = true;
        
        var retMaterial = {};
        retMaterial[materialId] = -materialCostNum;
        var retRefine = {};
        retRefine[selecetAttr] = attrAdd;

        resp.data.material = retMaterial;
        resp.data.refine = retRefine;

    }while(false);

    onHandled();
}

exports.rebuild = function(player, req, resp, onHandled) {
    do {
        if( isNaN(req.args.eid) ) {
            resp.code = 1; resp.desc = 'no valid args'; break;
        }

        var eid = +req.args.eid;
        var equip = player.user.equip[eid];
        if (!equip) {
            resp.code = 1; resp.desc = 'no equip'; break;
        }

        var equipNewType = null;
        if ("weapon" == equip.type) {
            equipNewType = "magic";
        } else if ("magic" == equip.type) {
            equipNewType = "weapon";
        } else {
            resp.code = 1; resp.desc = 'not weapon'; break;
        }

        var equipConf = gConfEquip[equip.level];
        if (!equipConf) {
            resp.code = 1; resp.desc = 'level conf invalid'; break;
        }

        var needMaterialNum = 1;
        var needMaterialId = equipConf.RebuildMaterial;
        if (!equipConf.RebuildMaterial) {
            resp.code = 1; resp.desc = 'can not rebuild'; break;
        }

        if (player.getInventory('material', needMaterialId) < needMaterialNum) {
            resp.code = 1; resp.desc = 'material not enough'; break;
        }
        
        equip.type = equipNewType;
        for (var slot in equip.gems) {
            var gem = equip.gems[slot];
            var defaultGem = gConfGlobal[equip.type.capWord() + "GemSlot"][slot-1];
            if (defaultGem) {
                var newGem = Math.floor(+defaultGem/100)*100 + (+gem)%100;
                equip.gems[slot] = newGem;
            }
        }
        player.addInventory('material', needMaterialId, -needMaterialNum);
        
        player.markDirty(util.format('equip.%d.type', eid));
        player.markDirty(util.format('equip.%d.gems', eid));
        player.roleDirty = true;

        var retMaterial = {};
        retMaterial[needMaterialId] = -needMaterialNum;
        resp.data.material = retMaterial;
        resp.data.equip = equip;
    }while(false);

    onHandled();
}

